package com.seckill.user.service.impl;

import cn.hutool.core.util.StrUtil;
import com.seckill.api.dto.user.LoginFormDTO;
import com.seckill.api.dto.user.UserDTO;
import com.seckill.common.domain.dto.LoginUserDTO;
import com.seckill.common.enums.UserType;
import com.seckill.common.exceptions.BadRequestException;
import com.seckill.common.exceptions.BizIllegalException;
import com.seckill.common.utils.AssertUtils;
import com.seckill.common.utils.BeanUtils;
import com.seckill.common.utils.UserContext;
import com.seckill.user.domain.po.User;
import com.seckill.user.domain.query.UserQuery;
import com.seckill.user.mapper.UserMapper;
import com.seckill.user.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;

import static com.seckill.user.constants.UserErrorInfo.Msg.*;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author zsc
 * @since 2025-05-14
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public Long exchangeUserIdWithPhone(String phone) {
        User user = lambdaQuery().eq(User::getPhone, phone).one();
        if (user == null) {
            throw new BizIllegalException("用户不存在");
        }
        return user.getId();
    }

    @Override
    public Integer queryUserType(Long id) {
        User user = getById(id);
        if (user == null) {
            throw new BizIllegalException("用户不存在");
        }
        return user.getType().getValue();
    }

    @Override
    public LoginUserDTO queryUserDetail(LoginFormDTO loginDTO) {
        // 1.判断登录方式
        Integer type = loginDTO.getType();
        User user = null;
        // 2.用户名和密码登录
        if (type == 1) {
            user = loginByPw(loginDTO);
        }
        // 3.验证码登录
        if (type == 2) {
            //todo 验证码登录
            //user = loginByVerifyCode(loginDTO.getCellPhone(), loginDTO.getPassword());
        }
        // 4.错误的登录方式
        if (user == null) {
            throw new BadRequestException(ILLEGAL_LOGIN_TYPE);
        }
        // 6.封装返回
        LoginUserDTO userDTO = new LoginUserDTO();
        userDTO.setUserId(user.getId());
        userDTO.setRoleId((long) user.getType().getValue());
        return userDTO;
    }

    @Override
    public List<UserDTO> queryUserByIds(Iterable<Long> ids) {
        List<User> users = lambdaQuery().in(User::getId, ids).list();
        return BeanUtils.copyList(users, UserDTO.class);
    }

    @Override
    public void registerUser(UserQuery rgisterQuery) {
        User user = BeanUtils.copyBean(rgisterQuery, User.class);
        //密码加密
        user.setPassword(passwordEncoder.encode(rgisterQuery.getPassword()));
        //默认为普通用户
        user.setType(UserType.USER);
        //保存
        save(user);

    }

    @Override
    public void updateUser(Long userId, UserQuery userQuery) {
        User user = BeanUtils.copyBean(userQuery, User.class);
        user.setId(userId);
        AssertUtils.isTrue(updateById(user), USER_ID_NOT_EXISTS);
    }

    @Override
    public void deductMoney(String pw, Integer amount) {
        log.info("开始扣款");
        // 1.校验密码
        User user = getById(UserContext.getUser());
        if(user == null || !passwordEncoder.matches(pw, user.getPassword())){
            // 密码错误
            throw new BizIllegalException("用户密码错误");
        }

        // 2.尝试扣款
        try {
            baseMapper.updateMoney(UserContext.getUser(), amount);
        } catch (Exception e) {
            throw new BizIllegalException("扣款失败");
        }
        log.info("扣款成功");
    }

    @Override
    public void deductsecMoney(Integer amount) {
        baseMapper.updateMoney(UserContext.getUser(), amount);
    }

    public User loginByPw(LoginFormDTO loginDTO) {
        // 1.数据校验
        String username = loginDTO.getUsername();
        String cellPhone = loginDTO.getCellPhone();
        if (StrUtil.isBlank(username) && StrUtil.isBlank(cellPhone)) {
            throw new BadRequestException(INVALID_UN);
        }
        // 2.根据用户名或手机号查询
        User user = lambdaQuery()
                .eq(StrUtil.isNotBlank(username), User::getUsername, username)
                .eq(StrUtil.isNotBlank(cellPhone), User::getPhone, cellPhone)
                .one();
        AssertUtils.isNotNull(user, INVALID_UN_OR_PW);
        // 3.校验密码
//        String password = passwordEncoder.encode(loginDTO.getPassword());
        if (!passwordEncoder.matches(loginDTO.getPassword(), user.getPassword())) {
            throw new BadRequestException(INVALID_UN_OR_PW);
        }
//        if(!password.equals(user.getPassword())){
//            throw new BadRequestException(INVALID_UN_OR_PW);
//        }
        return user;
    }
}
